{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python38364bitd9422d0e0f224c0ebaa082ef5b357e74",
   "display_name": "Python 3.8.3 64-bit"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[1.0469e-38, 9.3674e-39, 9.9184e-39],\n        [8.7245e-39, 9.2755e-39, 8.9082e-39],\n        [9.9184e-39, 8.4490e-39, 9.6429e-39],\n        [1.0653e-38, 1.0469e-38, 4.2246e-39],\n        [1.0378e-38, 9.6429e-39, 9.2755e-39]])\n"
    }
   ],
   "source": [
    "x = torch.empty(5, 3)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[0.4007, 0.6567, 0.5837],\n        [0.5543, 0.6275, 0.6864],\n        [0.3412, 0.9558, 0.6437],\n        [0.4972, 0.3123, 0.0910],\n        [0.5382, 0.7075, 0.0924]])\n"
    }
   ],
   "source": [
    "x = torch.rand(5, 3)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0]])\n"
    }
   ],
   "source": [
    "x = torch.zeros(5, 3, dtype=torch.long)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([1, 2, 4])\n"
    }
   ],
   "source": [
    "x = torch.tensor([1, 2, 4])\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[1., 1., 1.],\n        [1., 1., 1.],\n        [1., 1., 1.],\n        [1., 1., 1.],\n        [1., 1., 1.]], dtype=torch.float64)\ntensor([[ 0.1052, -1.1851, -0.3414],\n        [ 1.0510,  0.7956,  0.6260],\n        [-0.0797, -0.1273,  0.2926],\n        [-0.2679, -0.4116,  0.9994],\n        [-0.1020, -2.0411,  1.4664]])\n"
    }
   ],
   "source": [
    "x = x.new_ones(5, 3, dtype=torch.float64)\n",
    "print(x)\n",
    "\n",
    "x = torch.randn_like(x, dtype=torch.float)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "torch.Size([5, 3])\ntorch.Size([5, 3])\n"
    }
   ],
   "source": [
    "print(x.size())\n",
    "print(x.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[ 1.0677e+00, -5.5621e-01,  3.3981e-01],\n        [ 1.9494e+00,  1.6707e+00,  1.5460e+00],\n        [ 3.7874e-01,  7.5174e-01,  3.8895e-01],\n        [ 6.0355e-01, -1.3884e-03,  1.5421e+00],\n        [ 8.6186e-01, -1.8013e+00,  1.8268e+00]])\n"
    }
   ],
   "source": [
    "y = torch.rand(5, 3)\n",
    "print(x + y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[ 1.0677e+00, -5.5621e-01,  3.3981e-01],\n        [ 1.9494e+00,  1.6707e+00,  1.5460e+00],\n        [ 3.7874e-01,  7.5174e-01,  3.8895e-01],\n        [ 6.0355e-01, -1.3884e-03,  1.5421e+00],\n        [ 8.6186e-01, -1.8013e+00,  1.8268e+00]])\n"
    }
   ],
   "source": [
    "print(torch.add(x, y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[ 1.0677e+00, -5.5621e-01,  3.3981e-01],\n        [ 1.9494e+00,  1.6707e+00,  1.5460e+00],\n        [ 3.7874e-01,  7.5174e-01,  3.8895e-01],\n        [ 6.0355e-01, -1.3884e-03,  1.5421e+00],\n        [ 8.6186e-01, -1.8013e+00,  1.8268e+00]])\n"
    }
   ],
   "source": [
    "result = torch.empty(5, 3)\n",
    "torch.add(x, y, out=result)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[ 1.0677e+00, -5.5621e-01,  3.3981e-01],\n        [ 1.9494e+00,  1.6707e+00,  1.5460e+00],\n        [ 3.7874e-01,  7.5174e-01,  3.8895e-01],\n        [ 6.0355e-01, -1.3884e-03,  1.5421e+00],\n        [ 8.6186e-01, -1.8013e+00,  1.8268e+00]])\n"
    }
   ],
   "source": [
    "y.add_(x)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor(-0.1851)\ntensor(-0.1851)\n"
    }
   ],
   "source": [
    "y = x[0, 1]\n",
    "y += 1\n",
    "print(y)\n",
    "print(x[0, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])\n"
    }
   ],
   "source": [
    "y = x.view(15)\n",
    "z = x.view(-1, 5)\n",
    "print(x.size(), y.size(), z.size())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[ 1.1052,  0.8149,  0.6586],\n        [ 2.0510,  1.7956,  1.6260],\n        [ 0.9203,  0.8727,  1.2926],\n        [ 0.7321,  0.5884,  1.9994],\n        [ 0.8980, -1.0411,  2.4664]])\ntensor([ 1.1052,  0.8149,  0.6586,  2.0510,  1.7956,  1.6260,  0.9203,  0.8727,\n         1.2926,  0.7321,  0.5884,  1.9994,  0.8980, -1.0411,  2.4664])\n"
    }
   ],
   "source": [
    "x += 1 \n",
    "print(x)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[ 0.1052, -0.1851, -0.3414],\n        [ 1.0510,  0.7956,  0.6260],\n        [-0.0797, -0.1273,  0.2926],\n        [-0.2679, -0.4116,  0.9994],\n        [-0.1020, -2.0411,  1.4664]])\ntensor([ 1.1052,  0.8149,  0.6586,  2.0510,  1.7956,  1.6260,  0.9203,  0.8727,\n         1.2926,  0.7321,  0.5884,  1.9994,  0.8980, -1.0411,  2.4664])\n"
    }
   ],
   "source": [
    "x_cp = x.clone().view(15)\n",
    "x -= 1 \n",
    "print(x)\n",
    "print(x_cp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([-0.4700])\n-0.4699609875679016\n"
    }
   ],
   "source": [
    "x =torch.randn(1)\n",
    "print(x)\n",
    "print(x.item())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[1, 2]])\ntensor([[1],\n        [2],\n        [3]])\ntensor([[2, 3],\n        [3, 4],\n        [4, 5]])\n"
    }
   ],
   "source": [
    "x = torch.arange(1, 3).view(1, 2)\n",
    "print(x)\n",
    "y =torch.arange(1, 4).view(3, 1)\n",
    "print(y)\n",
    "print(x + y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "False\n"
    }
   ],
   "source": [
    "x = torch.tensor([1, 2])\n",
    "y = torch.tensor([3, 4])\n",
    "id_before = id(y)\n",
    "y = y + x \n",
    "print(id(y) == id_before)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "True\n"
    }
   ],
   "source": [
    "x = torch.tensor([2, 3])\n",
    "y = torch.tensor([3, 4])\n",
    "id_before = id(y)\n",
    "y[:] = y + x \n",
    "print(id(y) == id_before)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "True\n"
    }
   ],
   "source": [
    "x = torch.tensor([1, 2])\n",
    "y = torch.tensor([3, 4])\n",
    "id_before = id(y)\n",
    "torch.add(x, y, out=y)\n",
    "print(id(y) == id_before)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]\ntensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]\ntensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]\n"
    }
   ],
   "source": [
    "a = torch.ones(5)\n",
    "b = a.numpy()\n",
    "print(a, b)\n",
    "\n",
    "a += 1 \n",
    "print(a, b)\n",
    "b += 1 \n",
    "print(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "[1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)\n[2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)\n[3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)\n"
    }
   ],
   "source": [
    "import numpy as np \n",
    "a = np.ones(5)\n",
    "b = torch.from_numpy(a)\n",
    "print(a, b)\n",
    "\n",
    "a += 1 \n",
    "print(a, b)\n",
    "b += 1 \n",
    "print(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "[4. 4. 4. 4. 4.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)\n"
    }
   ],
   "source": [
    "c = torch.tensor(a)\n",
    "a += 1 \n",
    "print(a, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[1., 1.],\n        [1., 1.]], requires_grad=True)\nNone\n"
    }
   ],
   "source": [
    "x = torch.ones(2 ,2, requires_grad=True)\n",
    "print(x)\n",
    "print(x.grad_fn)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[3., 3.],\n        [3., 3.]], grad_fn=<AddBackward0>)\n<AddBackward0 object at 0x0000000014989F10>\n"
    }
   ],
   "source": [
    "y = x + 2 \n",
    "print(y)\n",
    "print(y.grad_fn)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "True False\n"
    }
   ],
   "source": [
    "print(x.is_leaf, y.is_leaf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[27., 27.],\n        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)\n"
    }
   ],
   "source": [
    "z = y * y * 3\n",
    "out= z.mean()\n",
    "print(z, out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "False\nTrue\n<SumBackward0 object at 0x0000000014B46D30>\n"
    }
   ],
   "source": [
    "a = torch.randn(2, 2)\n",
    "a = (a * 3) / (a -1)\n",
    "print(a.requires_grad)\n",
    "a.requires_grad_(True)\n",
    "print(a.requires_grad)\n",
    "b = (a * a).sum()\n",
    "print(b.grad_fn)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[27., 27.],\n        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)\ntensor([[4.5000, 4.5000],\n        [4.5000, 4.5000]])\n"
    }
   ],
   "source": [
    "z = y * y * 3\n",
    "out= z.mean()\n",
    "print(z, out)\n",
    "out.backward()\n",
    "print(x.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[5.5000, 5.5000],\n        [5.5000, 5.5000]])\ntensor([[1., 1.],\n        [1., 1.]])\n"
    }
   ],
   "source": [
    "out2 = x.sum()\n",
    "out2.backward()\n",
    "print(x.grad)\n",
    "\n",
    "out3 = x.sum()\n",
    "x.grad.data.zero_()\n",
    "out3.backward()\n",
    "print(x.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([[2., 4.],\n        [6., 8.]], grad_fn=<ViewBackward>)\n"
    }
   ],
   "source": [
    "x = torch.tensor([1.0, 2.0, 3.0, 4.0], requires_grad=True)\n",
    "y = 2 * x\n",
    "z = y.view(2, 2)\n",
    "print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([2.0000, 0.2000, 0.0200, 0.0020])\n"
    }
   ],
   "source": [
    "v = torch.tensor([[1.0, 0.1], [0.01, 0.001]], dtype=torch.float)\n",
    "z.backward(v)\n",
    "print(x.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "True\ntensor(1., grad_fn=<PowBackward0>) True\ntensor(1.) False\ntensor(2., grad_fn=<AddBackward0>) True\n"
    }
   ],
   "source": [
    "x =torch.tensor(1.0, requires_grad=True)\n",
    "y1 = x ** 2 \n",
    "with torch.no_grad():\n",
    "    y2 = x ** 2\n",
    "y3 = y1 + y2\n",
    "\n",
    "print(x.requires_grad)\n",
    "print(y1, y1.requires_grad)\n",
    "print(y2, y2.requires_grad)\n",
    "print(y3, y3.requires_grad)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor(2.)\n"
    }
   ],
   "source": [
    "y3.backward()\n",
    "print(x.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "tensor([1.])\nFalse\ntensor([100.], requires_grad=True)\ntensor([2.])\n"
    }
   ],
   "source": [
    "x = torch.ones(1, requires_grad=True)\n",
    "\n",
    "print(x.data)\n",
    "print(x.data.requires_grad) \n",
    "\n",
    "y = 2 * x \n",
    "x.data *= 100 \n",
    "\n",
    "y.backward()\n",
    "print(x)\n",
    "print(x.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ]
}